home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / haeberli / mtex / show.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  23KB  |  781 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. #include <gl/gl.h>
  18. #include <gl/device.h>
  19. #include <math.h>
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. #include "colors.h"
  23. #include "image.h"
  24. #include "types.h"
  25. #include "other.h"
  26.  
  27. #define USE_NORMAL 1
  28. #define USE_COLOR 2
  29. #define USE_TEXTURE 4
  30. #define X 0
  31. #define Y 1
  32. #define Z 2
  33. #define U 0
  34. #define V 1
  35.  
  36. #define PI 3.1415926535897
  37. #define SET2( A, B, C ) {(A)[0]=(B);(A)[1]=(C);}
  38. #define SETXYZ( A, B, C, D ) {(A)[X]=(B);(A)[Y]=(C);(A)[Z]=(D);}
  39. #define AVG2F( A, B ) (((A)+(B))/2.0)
  40. #define AVG3F( A, B, C ) (((A)+(B)+(C))/3.0)
  41. #define AVG4F( A, B, C, D ) (((A)+(B)+(C)+(D))/4.0)
  42. #define AVG2FXYZ( A, B, C ) {(A)[X]=AVG2F((B)[X],(C)[X]);(A)[Y]=AVG2F((B)[Y],(C)[Y]);(A)[Z]=AVG2F((B)[Z],(C)[Z]);}
  43.  
  44. #define COPY( A, B) {(A)[X]=(B)[X];(A)[Y]=(B)[Y];(A)[Z]=(B)[Z];}
  45. #define COPYVXYZ( A, B, C, D) {COPY((A).v1.xyz,(B));COPY((A).v2.xyz,(C));COPY((A).v3.xyz,(D));}
  46. #define COPY3V( A, B ) {COPY((A).v1,(B).v1);COPY((A).v2,(B).v2);COPY((A).v3,(B).v3);}
  47. #define COPY3N( A, B ) {COPY((A).v1,(B.v1));COPY((A).v2,(B).v2);COPY((A).v3,(B).v3);}
  48. #define FLIP( A ) {(A)[X]=-(A)[X];(A)[Y]=-(A)[Y];(A)[Z]=-(A)[Z];}
  49. #define DISTANCE( A, B ) \
  50. sqrtf(((A)[X]-(B)[X])*((A)[X]-(B)[X])+\
  51.       ((A)[Y]-(B)[Y])*((A)[Y]-(B)[Y])+\
  52.       ((A)[Z]-(B)[Z])*((A)[Z]-(B)[Z]))
  53. #define XYZ_LEN( A ) sqrtf((A)[X]*(A)[X]+(A)[Y]*(A)[Y]+(A)[Z]*(A)[Z])
  54. #define NORMALIZE( A, L ) {L=XYZ_LEN(A); if (L>0.0){(A)[X]/=L;(A)[Y]/=L;(A)[Z]/=L;}}
  55. #define CROSS3D( A, B, C ) { \
  56.   (A)[X] =  (B)[Y] * (C)[Z] - (B)[Z] * (C)[Y]; \
  57.   (A)[Y] = -(B)[X] * (C)[Z] + (B)[Z] * (C)[X]; \
  58.   (A)[Z] =  (B)[X] * (C)[Y] - (B)[Y] * (C)[X]; \
  59.    }
  60. #define SUBXYZ( A, B, C ) { \
  61.   (A)[X] =  (B)[X] - (C)[X]; \
  62.   (A)[Y] =  (B)[Y] - (C)[Y]; \
  63.   (A)[Z] =  (B)[Z] - (C)[Z]; \
  64.    }
  65. #define DIVXYZ( A, B ) { \
  66.   (A)[X] /= (B); \
  67.   (A)[Y] /= (B); \
  68.   (A)[Z] /= (B); \
  69.    }
  70.  
  71. typedef float point_t[3];
  72. typedef float tri_tex_t[6];
  73.  
  74. typedef struct {
  75.     point_t xyz;
  76.     point_t n;
  77.     float t[2];
  78.     long  abgr;
  79. } p9_t;
  80.  
  81.  
  82. typedef struct {
  83.     p9_t v1;
  84.     p9_t v2;
  85.     p9_t v3;
  86. } tri_t;
  87.  
  88. typedef float mat3x3_t[3][3];
  89.  
  90.  
  91. long primes[156] =
  92. {8627, 8629, 8641, 8647, 8663, 8669, 8677, 8681, 8689, 8693, 8699, 8707, 8713,
  93.  8719, 8731, 8737, 8741, 8747, 8753, 8761, 8779, 8783, 8803, 8807, 8819, 8821,
  94.  8831, 8837, 8839, 8849, 8861, 8863, 8867, 8887, 8893, 8923, 8929, 8933, 8941,
  95.  8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011, 9013, 9029, 9041, 9043, 9049,
  96.  9059, 9067, 9091, 9103, 9109, 9127, 9133, 9137, 9151, 9157, 9161, 9173, 9181,
  97.  9187, 9199, 9203, 9209, 9221, 9227, 9239, 9241, 9257, 9277, 9281, 9283, 9293,
  98.  9311, 9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377, 9391, 9397, 9403, 9413,
  99.  9419, 9421, 9431, 9433, 9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491, 9497,
  100.  9511, 9521, 9533, 9539, 9547, 9551, 9587, 9601, 9613, 9619, 9623, 9629, 9631,
  101.  9643, 9649, 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733, 9739, 9743, 9749,
  102.  9767, 9769, 9781, 9787, 9791, 9803, 9811, 9817, 9829, 9833, 9839, 9851, 9857,
  103.  9859, 9871, 9883, 9887, 9901, 9907, 9923, 9929, 9931, 9941, 9949, 9967, 9973};
  104.  
  105. Matrix identity = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1};
  106. long show_indexes[6];
  107. Boolean texmap_random;
  108. Boolean texture_loaded = FALSE;
  109. long map_rotation,tex_prop_select;
  110. long maximum_z;
  111. long texture_components_per_pixel,texture_width,texture_height;
  112. long seed;
  113. float my_noise;
  114. unsigned long *texture_image_in_mem;
  115. p9_t xa = {1.0, 0.0, 0.0};
  116. p9_t za = {0.0, 0.0, 1.0};
  117. p9_t org = {0.0, 0.0, 0.0};
  118. p9_t mid = {-0.7, 0.7, 0.0};
  119. float scrparams[] = {0., 0., 5.0};  /* Max-Z, Minsize, Maxsize */
  120. float texprops[] = {TX_MINFILTER,TX_MIPMAP_TRILINEAR,TX_MAGFILTER,TX_BILINEAR,
  121.                     TX_WRAP,TX_REPEAT,TX_NULL};
  122. float tevprops[] = {TV_COLOR,0.99,0.0,0.99,TV_MODULATE,TV_NULL};            
  123. float mat1[] = {
  124.    AMBIENT, .2, .2, .2,
  125.    DIFFUSE,  1, .1, .1,
  126.    SPECULAR, .7, .7, .7,
  127.    SHININESS, 30,
  128.    LMNULL      };
  129. float mat2[] = {
  130.    AMBIENT, .3, .3, .3,
  131.    DIFFUSE,  .5, 1., .3,
  132.    SPECULAR, .5, .5, .5,
  133.    SHININESS, 10,
  134.    LMNULL      };
  135. static float lm[] = {
  136.    AMBIENT, .7, .7, .7,
  137.    LOCALVIEWER, 1,
  138.    LMNULL           };
  139. static float lt[] = {
  140.    LCOLOR, 1, 1, 1,
  141.    POSITION, 20., -10., 10., 0,
  142.    LMNULL           };
  143.  
  144.    
  145. /********************************************************************************/   
  146.  
  147.  
  148. void draw_tri(tri_t *tri)
  149. {
  150. point_t normal,vect12,vect13,v_axis;
  151. float len,u_offset,v_offset,uv1[2],uv2[2],uv3[2];
  152. Angle angle;
  153.  
  154. /* Define coordinate axes: +U is 1-->2                          */
  155. /*                         +V is orthogonal to +U and to normal */
  156.  
  157.    uv1[U] = 0.0;
  158.    uv1[V] = 0.0;
  159.    uv2[V] = 0.0;
  160.    SUBXYZ(vect12,(*tri).v1.xyz,(*tri).v2.xyz);  /* 1-->2 */
  161.    uv2[U] = XYZ_LEN(vect12);                        /* Length of 1-->2 is U for vertex 2 */
  162.    DIVXYZ(vect12,uv2[U]);                           /* Normalize vect12 */
  163.    uv3[U] = DOT(vect12,vect13);                     /* Projection of 3 on 1-->2 line */
  164.    SUBXYZ(vect13,(*tri).v1.xyz,(*tri).v3.xyz);  /* 1-->3 */
  165.    CROSS3D(normal,vect12,vect13);               /* Normal is orthogonal to 1-->2 and 1-->3 */
  166.    NORMALIZE(normal,len);                       /* Normal vector should be length 1 */
  167.    CROSS3D(v_axis,normal,vect12);               /* V axis is ortho to normal and 1-->3 */   
  168.    uv3[V] = DOT(vect13,v_axis);                 /* Projection of 3 on V axis */
  169.    u_offset = (float)rand() / (float)RAND_MAX;
  170.    v_offset = (float)rand() / (float)RAND_MAX;
  171.    uv1[U] += u_offset;                          /* Translate U,Vs by random vector */
  172.    uv1[V] += v_offset;
  173.    uv2[U] += u_offset;
  174.    uv2[V] += v_offset;
  175.    uv3[U] += u_offset;
  176.    uv3[V] += v_offset;
  177.    
  178.    if (normal[Z] < 0.0) FLIP(normal);
  179.    if (texmap_random)
  180.       {
  181.       mmode(MTEXTURE);
  182.       angle = rand() / (RAND_MAX / 3600);
  183.       rotate(angle,'z');
  184.       mmode(MVIEWING);
  185.       }
  186.    bgnpolygon();
  187.       t2f(uv1); n3f(normal); v3f((*tri).v1.xyz);
  188.       t2f(uv2); n3f(normal); v3f((*tri).v2.xyz);
  189.       t2f(uv3); n3f(normal); v3f((*tri).v3.xyz);
  190.    endpolygon();
  191. }
  192.  
  193. void make_mat3x3 (mat3x3_t *mat, p9_t *axis, float angle)
  194. {
  195. float radians,s,c,t,x,y,z;
  196.  
  197. /* Make matrix for rotation about arbitrary axis */
  198. /* See Graphic Gems I, Page 466                  */
  199.  
  200.    radians = 2.0 * PI * angle / 360.;
  201.    if (angle >= 0.0)
  202.       s = sin(radians);
  203.    else 
  204.       s = -sin(-radians);
  205.    c = cos(radians);
  206.    t = 1.0 - c;
  207.    x = (*axis).xyz[X];
  208.    y = (*axis).xyz[Y];
  209.    z = (*axis).xyz[Z];
  210.    
  211.    (*mat)[X][X] = t * x * x + c;
  212.    (*mat)[X][Y] = t * x * y + s * z;
  213.    (*mat)[X][Z] = t * x * z - s * y;
  214.    (*mat)[Y][X] = t * x * y - s * z;
  215.    (*mat)[Y][Y] = t * y * y + c;
  216.    (*mat)[Y][Z] = t * y * z + s * x;
  217.    (*mat)[Z][X] = t * x * z + s * y;
  218.    (*mat)[Z][Y] = t * y * z - s * x;
  219.    (*mat)[Z][Z] = t * z * z + c;
  220. }
  221.  
  222.  
  223. void my_rotate (mat3x3_t *mat, p9_t *p, p9_t *center)
  224. {
  225. float new_x,new_y,new_z,new_nx,new_ny,new_nz;
  226.  
  227. /* Rotate point "p" around center point "center" using rotation matrix "mat" */
  228.  
  229.    (*p).xyz[X] -= (*center).xyz[X];
  230.    (*p).xyz[Y] -= (*center).xyz[Y];
  231.    (*p).xyz[Z] -= (*center).xyz[Z];
  232.  
  233.    new_x = (*p).xyz[X] * (*mat)[X][X] + (*p).xyz[Y] * (*mat)[X][Y] + (*p).xyz[Z] * (*mat)[X][Z];
  234.    new_y = (*p).xyz[X] * (*mat)[Y][X] + (*p).xyz[Y] * (*mat)[Y][Y] + (*p).xyz[Z] * (*mat)[Y][Z];
  235.    new_z = (*p).xyz[X] * (*mat)[Z][X] + (*p).xyz[Y] * (*mat)[Z][Y] + (*p).xyz[Z] * (*mat)[Z][Z];
  236.    new_nx = (*p).n[X] * (*mat)[X][X] + (*p).n[Y] * (*mat)[X][Y] + (*p).n[Z] * (*mat)[X][Z];
  237.    new_ny = (*p).n[X] * (*mat)[Y][X] + (*p).n[Y] * (*mat)[Y][Y] + (*p).n[Z] * (*mat)[Y][Z];
  238.    new_nz = (*p).n[X] * (*mat)[Z][X] + (*p).n[Y] * (*mat)[Z][Y] + (*p).n[Z] * (*mat)[Z][Z];
  239.  
  240.    (*p).xyz[X] = new_x + (*center).xyz[X];
  241.    (*p).xyz[Y] = new_y + (*center).xyz[Y];
  242.    (*p).xyz[Z] = new_z + (*center).xyz[Z];
  243.    (*p).n[X] = new_nx;
  244.    (*p).n[Y] = new_ny;
  245.    (*p).n[Z] = new_nz;
  246. }   
  247.    
  248. void pos_and_draw(mat3x3_t *, p9_t *, p9_t *, p9_t *, p9_t *);
  249.  
  250. void draw_twiz(long count, float twists)
  251. {
  252. mat3x3_t mat;
  253. p9_t p1,p2,p3,p4,cp,ra,old_p1,old_p2,old_p3,old_p4;
  254. float x_angle_step,ra_angle_step;
  255. float across,dist_1,dist_2,dist_3,dist_4,avg_step;
  256. long i;
  257.  
  258. /* "Twiz" is a square-crosssection torus with a twist */
  259.  
  260.    SETXYZ(p1.xyz, -0.5, 0.5, 0.0);   /* p1 - p4 are corners of square cross-section */
  261.    SETXYZ(p2.xyz, -0.5, 0.9, 0.0);
  262.    SETXYZ(p3.xyz, -0.9, 0.9, 0.0);
  263.    SETXYZ(p4.xyz, -0.9, 0.5, 0.0);
  264.    SETXYZ(p1.n,    1.0, 0.0, 0.0);
  265.    SETXYZ(p2.n,    0.0, 1.0, 0.0);
  266.    SETXYZ(p3.n,   -1.0, 0.0, 0.0);
  267.    SETXYZ(p4.n,    0.0,-1.0, 0.0);
  268.    SETXYZ(cp.xyz, -0.7, 0.7, 0.0);   /* cp is center of square...for its rotation */
  269.    SETXYZ(ra.xyz,  0.0, 0.0, 1.0);   /* ra is rotation axis...normal to square */
  270.    SET2(p1.t, 1.0, 0.0);    /* Bottom right */
  271.    SET2(p2.t, 0.0, 0.0);    /* Bottom left */
  272.    SET2(p3.t, 1.0, 0.0);    /* Bottom right */
  273.    SET2(p4.t, 0.0, 0.0);    /* Bottom left */
  274.    
  275.    x_angle_step = 360.0 / (float)count;    /* Degrees per step around torus */
  276.    ra_angle_step = twists * x_angle_step;  /* Degrees per step to twist cross-section */
  277.    across = ABS(p3.xyz[X] - p1.xyz[X]);    /* Across square */
  278.    lmbind(MATERIAL, 1);
  279.    texbind(TX_TEXTURE_0,1);
  280.     
  281.    for (i=0; i<count; i++)
  282.       {
  283.       memcpy(&old_p1,&p1,sizeof(p9_t));           /* Save corners and normals */
  284.       memcpy(&old_p2,&p2,sizeof(p9_t));
  285.       memcpy(&old_p3,&p3,sizeof(p9_t));
  286.       memcpy(&old_p4,&p4,sizeof(p9_t));
  287.       make_mat3x3(&mat,&ra,(float)ra_angle_step);  /* Twist rotation */
  288.       my_rotate(&mat,&p1,&cp);                     /* Twist the square around cp by ra_angle_step */
  289.       my_rotate(&mat,&p2,&cp);
  290.       my_rotate(&mat,&p3,&cp);
  291.       my_rotate(&mat,&p4,&cp);
  292.       make_mat3x3(&mat,&xa,x_angle_step);          /* Around-the-torus rotation */
  293.       my_rotate(&mat,&p1,&org);                    /* Sweep p1-p4 and cp around torus */
  294.       my_rotate(&mat,&p2,&org);
  295.       my_rotate(&mat,&p3,&org);
  296.       my_rotate(&mat,&p4,&org);
  297.       my_rotate(&mat,&cp,&org);
  298.       my_rotate(&mat,&ra,&org);                    /* Rotate ra around torus also */
  299.       dist_1 = DISTANCE(p1.xyz,old_p1.xyz);
  300.       dist_2 = DISTANCE(p2.xyz,old_p2.xyz);
  301.       dist_3 = DISTANCE(p3.xyz,old_p3.xyz);
  302.       dist_4 = DISTANCE(p4.xyz,old_p4.xyz);
  303.       avg_step = AVG4F(dist_1,dist_2,dist_3,dist_4) / across;
  304.       p1.t[Y] += avg_step;                         /* Advance texture Y */
  305.       p2.t[Y] += avg_step;
  306.       p3.t[Y] += avg_step;
  307.       p4.t[Y] += avg_step;
  308.       make_mat3x3(&mat,&za,10.0);                  /* Rotate 10 degrees around Z to position in scene */
  309.       pos_and_draw(&mat,&p1,&p2,&old_p2,&old_p1);  /* Draw slightly twisted quads for twiz sides */
  310.       pos_and_draw(&mat,&p2,&p3,&old_p3,&old_p2);
  311.       pos_and_draw(&mat,&p3,&p4,&old_p4,&old_p3);
  312.       pos_and_draw(&mat,&p4,&p1,&old_p1,&old_p4);
  313.       }
  314.    texbind(TX_TEXTURE_0,0);
  315. }
  316.       
  317. void draw_quad_n(p9_t *, p9_t *, p9_t *, p9_t *);
  318.  
  319. void pos_and_draw(mat3x3_t *mat, p9_t *pa, p9_t *pb, p9_t *pc, p9_t *pd)
  320. {
  321. p9_t pa_copy,pb_copy,pc_copy,pd_copy;
  322.  
  323.    memcpy(&pa_copy,pa,sizeof(p9_t)); 
  324.    memcpy(&pb_copy,pb,sizeof(p9_t));
  325.    memcpy(&pc_copy,pc,sizeof(p9_t));
  326.    memcpy(&pd_copy,pd,sizeof(p9_t));
  327.    my_rotate(mat,&pa_copy,&mid);
  328.    my_rotate(mat,&pb_copy,&mid);
  329.    my_rotate(mat,&pc_copy,&mid);
  330.    my_rotate(mat,&pd_copy,&mid);
  331.  
  332.    draw_quad_n(&pa_copy,&pb_copy,&pc_copy,&pd_copy);
  333. }
  334.  
  335. void draw_quad_n(p9_t *pa, p9_t *pb, p9_t *pc, p9_t *pd)
  336. {
  337. float array[3];
  338. Angle angle;
  339.  
  340.    if (texmap_random)
  341.       {
  342.       mmode(MTEXTURE);
  343.       angle = rand() / (RAND_MAX / 3600);
  344.       rotate(angle,'z');
  345.       mmode(MVIEWING);
  346.       }
  347.  
  348.    bgnpolygon();
  349.    t2f((*pa).t);
  350.    n3f((*pa).n);
  351.    v3f((*pa).xyz);
  352.    t2f((*pb).t);
  353.    n3f((*pa).n);
  354.    v3f((*pb).xyz);
  355.    t2f((*pc).t);
  356.    n3f((*pd).n);
  357.    v3f((*pc).xyz);
  358.    t2f((*pd).t);
  359.    n3f((*pd).n);
  360.    v3f((*pd).xyz);
  361.    endpolygon();
  362. }
  363.  
  364. void output_point(p9_t *p, long how)
  365. {
  366. float array3[3];
  367. float array2[2];
  368.    
  369.    if (how & USE_NORMAL)  n3f(  (*p).n);
  370.    if (how & USE_COLOR)   cpack((*p).abgr);
  371.    if (how & USE_TEXTURE) t2f(  (*p).t);
  372.    v3f((*p).xyz);
  373. }
  374.  
  375.  
  376. void draw_quad(p9_t *pa, p9_t *pb, p9_t *pc, p9_t *pd, long how)
  377. {
  378. Angle angle;
  379. /* Draw a polygon, using "how" as bit-vector of options */
  380.  
  381.    if (texmap_random)
  382.       {
  383.       mmode(MTEXTURE);
  384.       angle = rand() / (RAND_MAX / 3600);
  385.       rotate(angle,'z');
  386.       mmode(MVIEWING);
  387.       }
  388.       
  389.    bgnpolygon();
  390.    output_point(pa,how);
  391.    output_point(pb,how);
  392.    output_point(pc,how);
  393.    output_point(pd,how);
  394.    endpolygon();
  395. }
  396.  
  397. void draw_floor(long count)
  398. {
  399. long i,k;
  400. float istep,kstep;
  401. p9_t p1,p2,p3,p4;
  402.  
  403. /* Repeat pattern count x 4*count times on a horizontal plane */
  404.  
  405.    texbind(TX_TEXTURE_0,1);
  406.    tevbind(TV_ENV0,1);
  407.    cpack(0xffffffff);   /* Multiply this color! */
  408.  
  409.    p1.xyz[Z] = p2.xyz[Z] = p3.xyz[Z] = p4.xyz[Z] = -0.5;
  410.  
  411.    istep = 4.0 / (float)count;
  412.    kstep = 4.0 / (float)count;
  413.    p1.t[0] = 0.0;
  414.    p1.t[1] = 0.0;
  415.    p2.t[0] = 1.0;
  416.    p2.t[1] = 0.0;
  417.    p3.t[0] = 1.0;
  418.    p3.t[1] = 1.0;
  419.    p4.t[0] = 0.0;
  420.    p4.t[1] = 1.0;
  421.    for (i=0; i<count; i++)
  422.    for (k=0; k<4*count; k++)
  423.       {
  424.       p1.xyz[X] = -2.0 + istep * (float) i;
  425.       p1.xyz[Y] = -2.0 + kstep * (float) k;
  426.       p2.xyz[X] = -2.0 + istep * (float) (i+1);
  427.       p2.xyz[Y] = -2.0 + kstep * (float) k;
  428.       p3.xyz[X] = -2.0 + istep * (float) (i+1);
  429.       p3.xyz[Y] = -2.0 + kstep * (float) (k+1);
  430.       p4.xyz[X] = -2.0 + istep * (float) i;
  431.       p4.xyz[Y] = -2.0 + kstep * (float) (k+1);
  432.       if ((i & 1) == (k & 1)) 
  433.      p1.abgr = p2.abgr = p3.abgr = p4.abgr = 0; 
  434.       else
  435.      p1.abgr = p2.abgr = p3.abgr = p4.abgr = 0xffffff; 
  436.       draw_quad(&p1,&p2,&p3,&p4,USE_TEXTURE);
  437.       }
  438.    texbind(TX_TEXTURE_0,0);
  439. }
  440.  
  441. float pseudorandom(p9_t *end1, p9_t *end2, long seed)
  442. {
  443. long *long_ptr,xor,x1,y1,z1,x2,y2,z2,base;
  444. float frac;
  445.  
  446.    if (seed >= 156) seed = 0;
  447.    base = primes[seed++];
  448.    long_ptr = (long *)end1->xyz;
  449.    x1 = *long_ptr++;
  450.    y1 = *long_ptr++;
  451.    z1 = *long_ptr++;
  452.    long_ptr = (long *)end2->xyz;
  453.    x2 = *long_ptr++;
  454.    y2 = *long_ptr++;
  455.    z2 = *long_ptr++;
  456.    xor = x1 ^ y1 ^ z1 ^ x2 ^ y2 ^ z2;
  457.    frac = (float)ABS(xor % base) / (float)(base-1);
  458.    return(frac);
  459. }
  460.  
  461. void perturb(p9_t *end1, p9_t *end2, p9_t *mid)
  462. {
  463. float frac,len,min;
  464.  
  465.    min = (1.0 - my_noise) / 2.0;
  466.    frac = min + my_noise * pseudorandom(end1,end2,seed);
  467.    (*mid).xyz[X] = frac * (*end1).xyz[X] + (1.0 - frac) * (*end2).xyz[X];
  468.    (*mid).t[0] = frac * (*end1).t[0] + (1.0 - frac) * (*end2).t[0];
  469.    frac = min + my_noise * pseudorandom(end1,end2,seed+1);
  470.    (*mid).xyz[Y] = frac * (*end1).xyz[Y] + (1.0 - frac) * (*end2).xyz[Y];
  471.    (*mid).t[1] = frac * (*end1).t[1] + (1.0 - frac) * (*end2).t[1];
  472.    frac = min + my_noise * pseudorandom(end1,end2,seed);
  473.    (*mid).xyz[Z] = frac * (*end1).xyz[Z] + (1.0 - frac) * (*end2).xyz[Z];
  474.    len = DISTANCE((*end1).xyz,(*end2).xyz);
  475.    (*mid).xyz[Z] +=  my_noise * sqrtf(len) * pseudorandom(end1,end2,seed+3);
  476. }
  477.  
  478. void subdivide_triangle(tri_t *parent, long level)
  479. {
  480. tri_t child;
  481. tri_tex_t tri_tex;
  482. p9_t mid12,mid13,mid23;    
  483.  
  484. /* parent is the address of tri in build_mountain */
  485.  
  486.  
  487. /* Recursively subdivide triangle to make fractal mountain */
  488.  
  489.    if (level == 0)           /* Stop recursion? */
  490.       {
  491.       draw_tri(parent);      /* Draw it, don't subdivide it further */
  492.       return;
  493.       }
  494.       
  495. /* Connect side midpoints to make four children */
  496.  
  497.    perturb(&parent->v1,&parent->v2,&mid12);
  498.    perturb(&parent->v1,&parent->v3,&mid13);
  499.    perturb(&parent->v2,&parent->v3,&mid23);
  500.    
  501.    memcpy(&child.v1,&parent->v1,sizeof(p9_t));
  502.    memcpy(&child.v2,&mid12,sizeof(p9_t));
  503.    memcpy(&child.v3,&mid13,sizeof(p9_t));
  504.    subdivide_triangle(&child,level-1);
  505.    
  506.    memcpy(&child.v1,&parent->v2,sizeof(p9_t));
  507.    memcpy(&child.v2,&mid12,sizeof(p9_t));
  508.    memcpy(&child.v3,&mid23,sizeof(p9_t));
  509.    subdivide_triangle(&child,level-1);
  510.    
  511.    memcpy(&child.v1,&parent->v3,sizeof(p9_t));
  512.    memcpy(&child.v2,&mid13,sizeof(p9_t));
  513.    memcpy(&child.v3,&mid23,sizeof(p9_t));
  514.    subdivide_triangle(&child,level-1);
  515.    
  516.    memcpy(&child.v1,&mid12,sizeof(p9_t));
  517.    memcpy(&child.v2,&mid13,sizeof(p9_t));
  518.    memcpy(&child.v3,&mid23,sizeof(p9_t));
  519.    subdivide_triangle(&child,level-1);
  520.  }
  521.     
  522. void build_mountain(long detail)
  523. {
  524. tri_t tri;
  525.  
  526.    texbind(TX_TEXTURE_0,1);
  527.    lmbind(MATERIAL, 2);
  528.  
  529.    SETXYZ(tri.v1.xyz,-15.0,14.0,-8.0);       /* Initial large, wide, tilted triangle */
  530.    SETXYZ(tri.v2.xyz, 15.0,14.0,-8.0);
  531.    SETXYZ(tri.v3.xyz,  0.0,20.0,10.0);
  532.    SET2(tri.v1.t,-1.5,-0.4);
  533.    SET2(tri.v2.t, 1.5,-0.4);
  534.    SET2(tri.v3.t, 0.0, 1.4);
  535.    
  536.    subdivide_triangle(&tri,detail);
  537.    
  538.    texbind(TX_TEXTURE_0,0);
  539. }
  540.    
  541. unsigned long *format_texture(image_t *im)
  542. {
  543. long x,y,rgb;
  544. unsigned long *wptr,*texture;
  545. char *bptr;
  546. long *iptr;
  547. alpha_t *aptr;
  548.  
  549.    texture_width = im->interior_xsize;
  550.    texture_height = im->interior_ysize;
  551.    texture_components_per_pixel = 3;
  552.    if (im->whole_alpha_org != NULL) texture_components_per_pixel = 4;
  553.    texture = (unsigned long *)calloc(im->interior_xsize * im->interior_ysize,
  554.                                      texture_components_per_pixel);
  555.    wptr = texture;                        /* For ABGR format */
  556.    bptr = (char *)texture;                /* In case we go byte by byte (BGR) */
  557.    iptr = im->interior_org;               /* Destination: lrectread format */
  558.    aptr = im->interior_alpha_org;         /* Source: alpha as array of char */
  559.    for (y=0; y<im->interior_ysize; y++)
  560.       {
  561.       if (texture_components_per_pixel == 3)
  562.          for (x=0; x<im->interior_xsize; x++)  
  563.             {
  564.             *bptr++ = CLAMP511 (EXTRACT_BLU(*iptr)) >> 1;
  565.             *bptr++ = CLAMP1023(EXTRACT_GRN(*iptr)) >> 2;
  566.             *bptr++ = CLAMP1023(EXTRACT_RED(*iptr)) >> 2;
  567.         iptr++;
  568.             } 
  569.       else if (texture_components_per_pixel == 4)
  570.          for (x=0; x<im->interior_xsize; x++)
  571.         {
  572.         rgb = *iptr++;
  573.         *wptr++ = LARGE_TO_888(rgb) | *aptr++ << 24;
  574.         }
  575.         
  576.       iptr += im->pixels_interior_wrap;
  577.       }
  578.    return(texture);
  579. }
  580.  
  581.  
  582.       
  583.       
  584. void draw_texture_scene(long j)
  585. {
  586. long count,fractalaciousness,floor_repeats;
  587. float twists;
  588.  
  589. /*   if (!getgdesc(GD_TEXTURE)) return;  */
  590.    
  591.    mmode(MVIEWING);
  592.    pushmatrix();
  593.    perspective(700,1.0,0.1,50.0);   /* 70 degree view, 1:1, near = .1, far = 50 */
  594.    polarview(2.6,0,900,0);
  595.    zbuffer(TRUE); 
  596.    subpixel(TRUE);
  597.    if (!texture_loaded)
  598.       {
  599.       texdef2d(1,texture_components_per_pixel,texture_width,texture_height,
  600.             texture_image_in_mem,0,texprops);
  601.       tevdef(1,0,tevprops);
  602.       scrsubdivide(SS_DEPTH,scrparams);
  603.       lmdef(DEFMATERIAL, 1, 0, mat1);
  604.       lmdef(DEFMATERIAL, 2, 0, mat2);
  605.       lmdef(DEFLIGHT, 1, 0, lt);
  606.       lmdef(DEFLMODEL, 1, 0, lm);
  607.       lmbind(LMODEL, 1);
  608.       lmbind(LIGHT0, 1);  
  609.       maximum_z = getgdesc(GD_ZMAX);
  610.       texture_loaded = TRUE;
  611.       }
  612.       
  613.    czclear(IBC,maximum_z);
  614.    
  615.    count = 50;
  616.    twists = 0.25;
  617.    floor_repeats = 10;
  618.    fractalaciousness = 7;
  619.    my_noise = 0.8;
  620.    seed = 0;
  621. /*   
  622.    mmode(MTEXTURE);
  623.    loadmatrix(identity);
  624. */   
  625.    mmode(MVIEWING);
  626.    draw_floor(floor_repeats);
  627.    build_mountain(fractalaciousness);
  628.    draw_twiz(count,twists);
  629.    mmode(MVIEWING);
  630.    ortho2(0,851,0,551);
  631.    popmatrix();
  632.    zbuffer(FALSE); 
  633.    subpixel(FALSE);
  634.    redisplay_all_widgets();
  635. }
  636.       
  637. void show_buttons(long j)
  638. {
  639. long k,l;
  640.  
  641.    if (show_indexes[0] == j)
  642.       {
  643.       if (ipt[j].data == 1) return;
  644.       ipt[j].data = 1;
  645.       ipt[j].redisplay_ui_proc(j);
  646.       k = show_indexes[1];
  647.       if (ipt[j].data == 1 && ipt[k].data == 1)
  648.          {
  649.      ipt[k].data = 0;
  650.      ipt[k].redisplay_ui_proc(k);
  651.      }
  652.       texmap_random = ipt[j].data;
  653.       draw_texture_scene(0);
  654.       }
  655.       
  656.    else if (show_indexes[1] == j)
  657.       {
  658.       if (ipt[j].data == 1) return;
  659.       ipt[j].data = 1;
  660.       ipt[j].redisplay_ui_proc(j);
  661.       k = show_indexes[0];
  662.       if (ipt[j].data == 1 && ipt[k].data == 1)
  663.          {
  664.      ipt[k].data = 0;
  665.      ipt[k].redisplay_ui_proc(k);
  666.      }
  667.       texmap_random = ipt[j].data;
  668.       draw_texture_scene(0);
  669.       }
  670.       
  671.    else if (show_indexes[2] == j)
  672.       {
  673.       if (ipt[j].data == 1) return;
  674.       ipt[j].data = 1;
  675.       ipt[j].redisplay_ui_proc(j);
  676.       k = show_indexes[3];
  677.       l = show_indexes[4];
  678.       if (ipt[j].data == 1 && ipt[k].data == 1)
  679.          {
  680.      ipt[k].data = 0;
  681.      ipt[k].redisplay_ui_proc(k);
  682.      }
  683.       if (ipt[j].data == 1 && ipt[l].data == 1)
  684.          {
  685.      ipt[l].data = 0;
  686.      ipt[l].redisplay_ui_proc(l);
  687.      }
  688.       tex_prop_select = TX_POINT;
  689.       texprops[1] = TX_POINT;
  690.       texprops[3] = TX_POINT;
  691.       texdef2d(1,texture_components_per_pixel,texture_width,texture_height,
  692.                texture_image_in_mem,0,texprops);
  693.       draw_texture_scene(0);
  694.       }
  695.  
  696.    else if (show_indexes[3] == j)
  697.       {
  698.       if (ipt[j].data == 1) return;
  699.       ipt[j].data = 1;
  700.       ipt[j].redisplay_ui_proc(j);
  701.       k = show_indexes[2];
  702.       l = show_indexes[4];
  703.       if (ipt[j].data == 1 && ipt[k].data == 1)
  704.          {
  705.      ipt[k].data = 0;
  706.      ipt[k].redisplay_ui_proc(k);
  707.      }
  708.       if (ipt[j].data == 1 && ipt[l].data == 1)
  709.          {
  710.      ipt[l].data = 0;
  711.      ipt[l].redisplay_ui_proc(l);
  712.      }
  713.       tex_prop_select = TX_BILINEAR;
  714.       texprops[1] = TX_BILINEAR;
  715.       texprops[3] = TX_BILINEAR;
  716.       texdef2d(1,texture_components_per_pixel,texture_width,texture_height,
  717.                texture_image_in_mem,0,texprops);
  718.       draw_texture_scene(0);
  719.      }
  720.  
  721.    else if (show_indexes[4] == j)
  722.       {
  723.       if (ipt[j].data == 1) return;
  724.       ipt[j].data = 1;
  725.       ipt[j].redisplay_ui_proc(j);
  726.       k = show_indexes[2];
  727.       l = show_indexes[3];
  728.       if (ipt[j].data == 1 && ipt[k].data == 1)
  729.          {
  730.      ipt[k].data = 0;
  731.      ipt[k].redisplay_ui_proc(k);
  732.      }
  733.       if (ipt[j].data == 1 && ipt[l].data == 1)
  734.          {
  735.      ipt[l].data = 0;
  736.      ipt[l].redisplay_ui_proc(l);
  737.      }
  738.       tex_prop_select = TX_MIPMAP_TRILINEAR;
  739.       texprops[1] = TX_MIPMAP_TRILINEAR;
  740.       texprops[3] = TX_BILINEAR;
  741.       texdef2d(1,texture_components_per_pixel,texture_width,texture_height,
  742.                texture_image_in_mem,0,texprops);
  743.       draw_texture_scene(0);
  744.       }
  745.       
  746.    else if (show_indexes[5] == j)
  747.       {
  748.       map_rotation += 90;
  749.       if (map_rotation > 270) map_rotation = 0;
  750.       mmode(MTEXTURE);
  751.       rotate(900,'z');
  752.       mmode(MVIEWING);
  753.       draw_texture_scene(0);
  754.       }
  755.       
  756.    else
  757.       {
  758.       printf("Show_button called with j = %d\n",j);
  759.       exit(15);
  760.       }
  761. }
  762.  
  763.      
  764. void cleanup_show()
  765. {
  766.    turn_off_all_widgets();
  767. }
  768.  
  769. void reveal_coord(char *text, float x, float y, long color)
  770. {
  771. char mess[100];
  772.  
  773.    sprintf(mess,"%5.2f,%5.2f,0.0 %s",x,y,text);
  774.    cpack(color);
  775.    cmov(x,y,0.0);
  776.    charstr(mess);
  777.    sginap(100);
  778. }
  779.      
  780.      
  781.